package gaileenchess;

public class HumanPlayer extends Player
{
    public static boolean print = true;
    
    public HumanPlayer(Common.Side s, Board b)
    {
       super(s, b);
    }
    //promote pawn to another piece
    public Piece.Type promote()
    {
        System.out.println("To which piece would you like to promote? ([Q]ueen, [R]ook, [B]ishop, [K]night)");
        String p = Main.in.nextLine().toUpperCase();
        while(true)
        {
            
            if (p.equals("Q") || p.equals("QUEEN")) 
            {
                return Piece.Type.QUEEN;
            }
            if (p.equals("R") || p.equals("ROOK"))
            {
                return Piece.Type.ROOK;
            }
            if (p.equals("B") || p.equals("BISHOP"))
            {
                return Piece.Type.BISHOP;
            }
            if (p.equals("K") || p.equals("KNIGHT"))
            {
                return Piece.Type.KNIGHT;
            }
            System.out.println("Invalid input, try again.");
            System.out.println("To which piece would you like to promote? ([Q]ueen, [R]ook, [B]ishop, [K]night)");
            p = Main.in.nextLine().toUpperCase();
        }
        
    }
    
    // gets command-line input and parses it into a command and arguments. Will need to be changed when we implement a GUI
    public Command getCommand()
    {
        if(print)
        {
            System.out.print("> "); // prompt the player
        }
        String[] cmd = Main.in.nextLine().toUpperCase().split(" ", 0); // split command from arguments
        int cmdsize = cmd.length;
        
        Command.Cmd type = Command.Cmd.INVALID;
        Board.Position[] args = null;

        if(cmd[0].equals("N") || cmd[0].equals("NEW"))
        {
            type = Command.Cmd.NEW;
        }
        else if(cmd[0].equals("Q") || cmd[0].equals("E") || cmd[0].equals("QUIT") || cmd[0].equals("EXIT"))
        {
            type = Command.Cmd.QUIT;
        }
        else if(cmd[0].equals("F") || cmd[0].equals("FORFEIT"))
        {
            type = Command.Cmd.FORFEIT;
        }
        else if((cmd[0].equals("M") || cmd[0].equals("MOVE")) && cmdsize == 3 /* to prevent error for args */)
        {
            type = Command.Cmd.MOVE;
            
            // MOVE takes 2 arguments
            args = new Board.Position[2];
            args[0] = Common.stringToPos(cmd[1]);
            args[1] = Common.stringToPos(cmd[2]);
            
            // make sure they were valid
            if(args[0] == null || args[1] == null)
            {
                type = Command.Cmd.INVALID;
                args = null;
            }
        }
        else if(cmd[0].equals("D") || cmd[0].equals("DISPLAY"))
        {
            type = Command.Cmd.DISPLAY;
        }
        else if(cmd[0].equals("H") || cmd[0].equals("?") || cmd[0].equals("HELP"))
        {
            type = Command.Cmd.HELP;
        }
        else if(cmd[0].equals("S") || cmd[0].equals("SETUP"))
        {
            type = Command.Cmd.SETUP;
        }
        else if((cmd[0].equals("V") || cmd[0].equals("VALID")) && cmdsize == 2 /* to prevent error for args */)
        {
            type = Command.Cmd.VALID;
            
            // VALID takes 1 argument
            args = new Board.Position[1];
            args[0] = Common.stringToPos(cmd[1]);
            
            // make sure it was valid
            if(args[0] == null)
            {
                type = Command.Cmd.INVALID;
                args = null;
            }
        }
        else if(cmd[0].equals("HINT"))
        {
            type = Command.Cmd.HINT;
        }
        else
        {
            type = Command.Cmd.INVALID;
        }
        
        return new Command(type, args);
    }
    
    public boolean confirm()
    {
        String response;
        
        while(true)
        {
            System.out.print("Are you sure? (Y[es]/N[o]): ");
            response = Main.in.nextLine().toUpperCase();
            
            if(response.equals("Y") || response.equals("YES"))
            {
                return true;
            }
            else if(response.equals("N") || response.equals("NO"))
            {
                return false;
            }
        }
    }
    
    public Piece[][] getSetup()
    {    
        String[] input = new String[0];
        Piece[][] config = new Piece[8][8];
        System.out.println("Input your board configuration");
        boolean success = true;
        Common.Side side = null;
        
        for(int x = 7; x >= 0; x--)
        {
            input = Main.in.nextLine().toUpperCase().split(" ");
            
            if(input.length != 8)
            {
                System.out.println("Invalid Setup");
                return null;
            }
            
            for(int y = 0; y < 8; y++)
            {
                boolean empty = false;
                
                if(input[y].length() != 2)
                {
                    System.out.println("Invalid Setup");
                    return null;
                }
                
                switch(input[y].charAt(0))
                {
                    case 'W':
                    side = Common.Side.WHITE;
                    break;
                    
                    case 'B':
                    side = Common.Side.BLACK;
                    break;
                    
                    case '*':
                    empty = true;
                    break;
                    
                    default:
                    success = false;
                }
                
                if(success && !empty)
                {
                    switch(input[y].charAt(1))
                    {
                        case 'B':
                        Board.addPiece(config, new Bishop(side, x, y));
                        break;
                        
                        case 'K':
                        Board.addPiece(config, new King(side, x, y));
                        break;
                        
                        case 'N':
                        Board.addPiece(config, new Knight(side, x, y));
                        break;
                        
                        case 'P':
                        Board.addPiece(config, new Pawn(side, x, y));
                        break;
                        
                        case 'Q':
                        Board.addPiece(config, new Queen(side, x, y));
                        break;
                        
                        case 'R':
                        Board.addPiece(config, new Rook(side, x, y));
                        break;
                        
                        default:
                        success = false;
                    }
                }
                
                if(!success)
                {
                    System.out.println("Invalid Setup");
                    return null;
                }
            }
        }
        
        return config;
    }
    
    public Player newP(Board board)
    {
        return new HumanPlayer(this.side, board);
    }
}
